package main

import (
	"fmt"
	"mss/internal/app/mss"
	"net"
	"os"
	"os/signal"
	"syscall"

	"gopkg.in/alecthomas/kingpin.v2"
)

// 全局常量
var (
	appName    = "mss"
	appVersion = "0.0.1"

	cliapp             = kingpin.New("mss", "")
	version            = cliapp.Command("version", "print version.")
	updateCmd          = cliapp.Command("update", "批量修改寄存器状态")
	updateWhichArg     = updateCmd.Arg("which", "选择哪些设备，语法：port1:addr1-addr2,port2:addr1-addr2").Required().String()
	writeDriverFileArg = updateCmd.Arg("file", "包含寄存器值列表的文件，语法跟mss_devices中的设备文件一致").String()
	addCmd             = cliapp.Command("add", "批量添加设备")
	addWhichArg        = addCmd.Arg("which", "选择哪些设备，语法：port1:addr1-addr2,port2:addr1-addr2").Required().String()
)

func main() {
	if len(os.Args) == 1 {

	} else {
		cmd := kingpin.MustParse(cliapp.Parse(os.Args[1:]))

		//
		// 命令路由
		//

		switch cmd {
		case version.FullCommand():
			fmt.Println(appName + " " + appVersion)
			os.Exit(0)
		case addCmd.FullCommand():
			err := mss.BatchAddDevices(*addWhichArg)
			if err != nil {
				fmt.Fprintln(os.Stderr, "执行失败:", err.Error())
				os.Exit(1)
			}
			fmt.Println("执行成功")
			os.Exit(0)
		case updateCmd.FullCommand():
			err := mss.BatchUpdateDevices(*updateWhichArg, *writeDriverFileArg)
			if err != nil {
				fmt.Fprintln(os.Stderr, "执行失败:", err.Error())
				os.Exit(1)
			}
			fmt.Println("执行成功")
			os.Exit(0)
		}
	}

	if isProcessExist() {
		fmt.Fprintln(os.Stderr, "mss is already running")
		os.Exit(1)
	}
	if err := mss.Run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// 创建一个信号通道
	sigCh := make(chan os.Signal, 1)

	// 注册要监听的信号
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	for sig := range sigCh {
		fmt.Printf("接收到信号: %v\n", sig)
		return
	}
}

// isProcessExist 检查进程是否存在
func isProcessExist() bool {
	listener, err := net.Listen("tcp", "127.0.0.1:27907")
	if err != nil {
		return true
	}

	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				return
			}
			conn.Close()
		}
	}()

	return false
}
